package com.capsulode.excel.conversion.impl;


import com.capsulode.excel.conversion.Converter;
import com.capsulode.excel.exception.CellTypeNotExpectException;
import com.capsulode.excel.exception.ConversionFailException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class LongConverter implements Converter<Long> {
    @Override
    public Long convert(Cell cell) throws CellTypeNotExpectException {

        if (CellType.NUMERIC.equals(cell.getCellTypeEnum())
                || CellType.FORMULA.equals(cell.getCellTypeEnum())) {
            return roundHalfUp(cell.getNumericCellValue());
        }

        if (CellType.BLANK.equals(cell.getCellTypeEnum())) {
            return null;
        }
        if (CellType.STRING.equals(cell.getCellTypeEnum())) {
            String stringCellValue = cell.getStringCellValue().trim();
            if (stringCellValue.isEmpty()) {
                return null;
            }
            try {
                return Long.parseLong(stringCellValue);
            } catch (NumberFormatException ex) {
                throw new CellTypeNotExpectException(cell.getRowIndex(), cell.getColumnIndex(), "无效的数字：" + cell, ex);
            }
        }
        throw new CellTypeNotExpectException(cell.getRowIndex(), cell.getColumnIndex());
    }

    @Override
    public void serialize(Object value, Cell cell) throws ConversionFailException, CellTypeNotExpectException {
        if (value instanceof Number) {
            long val = ((Number) value).longValue();
            cell.setCellValue(val);
            return;
        }
        if (value instanceof CharSequence) {
            long val = Long.parseLong(value.toString());
            cell.setCellValue(val);
            return;
        }
        throw new CellTypeNotExpectException(cell.getRowIndex(), cell.getColumnIndex());
    }

    private long roundHalfUp(double d) {
        return new BigDecimal(d).setScale(0, RoundingMode.HALF_UP).longValue();
    }
}
